//
//  ViewController.swift
//  FaceVerify
//
//  Created by duzexu on 2017/3/2.
//  Copyright © 2017年 duzexu. All rights reserved.
//

import UIKit
import Foundation
import Alamofire
import Moya
import MoyaSugar
import HandyJSON
import PKHUD
import RealmSwift
import RxSwift

class ViewController: UIViewController {
    
    @IBOutlet weak var imageViewL: ImagePickerView!
    @IBOutlet weak var imageViewR: ImagePickerView!
    @IBOutlet weak var labelL: UILabel!
    @IBOutlet weak var labelR: UILabel!
    @IBOutlet weak var resultLabel: UILabel!
    
    let provider = RxMoyaSugarProvider<ApiManager>()
    
    var result: Dictionary<String, DetectResult>! = [:]
    let realm = try! Realm()
    let dispose = DisposeBag()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        imageViewL.delegate = self
        imageViewR.delegate = self
    }

    // MARK: - Action
    @IBAction func compareAction(_ sender: Any) {
        if imageViewL.vaild && imageViewR.vaild {
            if let face1 = result[imageViewL.imagePath!], let face2 = result[imageViewR.imagePath!] {
                HUD.show(.systemActivity)
                provider.request(.verifyFace(faceId1: face1.faceId!, faceId2: face2.faceId!)).subscribe({ (event) in
                    switch event {
                    case let .next(response):
                        let json = try! response.mapJSON() as! NSDictionary
                        guard (json["error"]) != nil else {
                            HUD.flash(.success)
                            let identical = json["isIdentical"] as! Bool ? "是" : "否"
                            let confidence = json["confidence"] as! NSNumber
                            self.resultLabel.text = "相似度：\(Float(confidence)*100)% \n 是否为同一人：\(identical)"
                            return;
                        }
                        HUD.flash(.error)
                    case .error(_):
                        HUD.flash(.error)
                    default:
                        break
                    }
                }).addDisposableTo(dispose)
            }
        }
    }

}

extension ViewController: ImagePickerViewDelegate {
    public func didSelectWithImage(imageView: ImagePickerView, image: UIImage) {
        if let path = imageView.imagePath {
            let data = search(imagePath: path)
            if let d = data {
                let detect = JSONDeserializer<DetectResult>.deserializeFrom(json: d.faceData)
                if imageView == self.imageViewL {
                    self.labelL.text = detect?.string()
                }else{
                    self.labelR.text = detect?.string()
                }
                self.result[d.imagePath!] = detect
            }else{
                imageView.isLoading = true
                DispatchQueue.global().async {
                    let temp = NSTemporaryDirectory().appendingFormat("%d",floor(NSDate().timeIntervalSince1970))
                    let data = image.compressBelowMaxLength(maxLength: 1024*300)
                    try! data?.write(to: NSURL.fileURL(withPath: temp))
                    DispatchQueue.main.async {
                        self.detectImage(localPath: imageView.imagePath!, tempPath: temp, completion: { [weak self] (result, localPath, rawString) in
                            imageView.isLoading = false
                            if imageView == self?.imageViewL {
                                self?.labelL.text = result?.string()
                            }else{
                                self?.labelR.text = result?.string()
                            }
                            if let r = result {
                                self?.save(result: r, imagePath: localPath, rawString: rawString!)
                            }
                        })
                    }
                }
            }
        }
    }

}

extension ViewController {
    
    public typealias Completion = (DetectResult?, String, String?) -> Void
    
    func detectImage(localPath: String, tempPath: String, completion: @escaping Completion) -> Void {
        provider
            .request(.uploadImage(tempPath))
            .mapArray(DetectResult.self)
            .subscribe { [weak self] (event) in
                switch event {
                case let .next(result):
                    if result.count > 0 {
                        let r = result[0] as DetectResult
                        self?.result[localPath] = r
                        completion(r, localPath, r.toJSONString())
                    }else{
                        completion(nil,localPath,nil)
                    }
                case .error(_):
                    completion(nil,localPath,nil)
                default:
                    break
                }
            }
            .addDisposableTo(dispose)
    }
}

extension ViewController {
    func save(result: DetectResult, imagePath: String, rawString: String) -> Void {
        let imageData = ImageData(value: ["imagePath":imagePath,"faceId":result.faceId,"faceData":rawString])
        try! realm.write {
            realm.add(imageData)
        }
    }
    
    func search(imagePath: String) -> ImageData? {
        let result = realm.objects(ImageData.self).filter("imagePath = %@", imagePath)
        if result.count > 0 {
            let data = result[0] as ImageData
            if NSDate().timeIntervalSince1970 - data.time.timeIntervalSince1970 < 23*60*60 {
                return data
            }else{
                try! realm.write {
                    realm.delete(data)
                }
            }
        }
        return nil;
    }
}
